package com.dianban.controller.nengliang;

import com.alibaba.fastjson.JSONObject;
import com.dianban.base.ResultCode;
import com.dianban.base.ResultVo;
import com.dianban.config.redis.RedisConstant;
import com.dianban.config.redis.RedisUtil;
import com.dianban.controller.BaseController;
import com.dianban.entity.FacePayConfig;
import com.dianban.entity.StoreGuide;
import com.dianban.entity.User;
import com.dianban.service.FacePayConfigService;
import com.dianban.service.StoreGuideService;
import com.dianban.service.UserService;
import com.dianban.service.WxUserService;
import com.dianban.utils.IdGen;
import com.dianban.utils.MD5;
import com.dianban.utils.TencentSmsUtils;
import com.dianban.weixin.util.HttpUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

@Api(value = "ApiAuthController", description = "授权控制器")
@RestController
@RequestMapping(value = "${interfacePath}/nengliang/auth/")
public class ApiAuthController extends BaseController {

    @Value("${rongyaotuadmin.domain}")
    private String rongyaotuadminDomain;
    @Value("${rongyaotuapi.domain}")
    private String rongyaotuapiDomain;

    @Autowired
    private UserService userService;
    @Autowired
    private WxUserService wxUserService;
    @Autowired
    private StoreGuideService storeGuideService;
    @Autowired
    private FacePayConfigService facePayConfigService;

    // 调用php那边接口提供用户注册验证码以及用户注册逻辑

    @ApiOperation(notes = "sendCode", httpMethod = "GET", value = "发送短信验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "type", value = "注册1，绑定2，找回密码3", required = true, paramType = "query", dataType = "string"),
    })
    @RequestMapping(value = "sendCode", method = RequestMethod.GET)
    public ResultVo sendCode(String mobile, String type, HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isBlank(mobile)) {
            return ResultVo.error(ResultCode.ERROR, "手机号码不能为空");
        }
        try {
            //注册时候用的短信验证码获取接口，http://yun2.dianbang-st.com/apiv1/user/sendSms
            // 参数event(值为register),mobile,new_mobile
            if (StringUtils.isNotBlank(type) && ("1".equals(type) || "3".equals(type))) {
                String event = "register";
                if ("3".equals(type)) {
                    event = "reset";
                }
                // 调用php接口
                String url = rongyaotuapiDomain + "/apiv1/user/sendSms";
                String current = System.currentTimeMillis() + "";
                Map requestMap = new HashMap<>();
                requestMap.put("mobile", mobile);
                requestMap.put("event", event);
                requestMap.put("new_mobile", mobile);
                requestMap.put("t", current);
                // {"code":0,"result":{},"msg":"账号已存在"}
                // {"code":1,"result":{},"msg":"发送成功"}
                String resultStr = HttpUtils.sendPost(url, "mobile=" + mobile + "&event=" + event + "&new_mobile=" + mobile + "&t=" + current + "&sign=" + getSign(requestMap));
                if (StringUtils.isNotBlank(resultStr)) {
                    JSONObject jsonObject = JSONObject.parseObject(resultStr);
                    if (jsonObject != null) {
                        if (jsonObject.get("code") != null && "1".equalsIgnoreCase(String.valueOf(jsonObject.get("code")))) {
                            return ResultVo.success("", "发送成功");
                        } else {
                            return ResultVo.error(ResultCode.ERROR, String.valueOf(jsonObject.get("msg")));
                        }
                    }
                }
            } else if ("2".equals(type)) {
                String code = String.valueOf((int) (Math.random() * 9000 + 1000));
                RedisUtil.set(mobile, code, 120);
                TencentSmsUtils.sendSms("4", mobile, code, "");
                return ResultVo.success("", "发送成功");
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return ResultVo.error(ResultCode.ERROR, "发送失败");
    }

    @ApiOperation(notes = "register", httpMethod = "POST", value = "用户注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "invitecode", value = "推荐码", required = true, paramType = "query", dataType = "string"),
    })
    @RequestMapping(value = "register", method = RequestMethod.POST)
    public ResultVo register(String mobile, String password, String code, String invitecode, HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isBlank(mobile)) {
            return ResultVo.error(ResultCode.ERROR, "手机号码不能为空");
        }
        try {
            //现有的用户注册，http://yun2.dianbang-st.com/apiv1/user/register
            // 注册接口参数有mobile,password,code,invitecode,trade_password,team_id
            String url = rongyaotuapiDomain + "/apiv1/user/register";
            String current = System.currentTimeMillis() + "";
            Map requestMap = new HashMap<>();
            requestMap.put("mobile", mobile);
            requestMap.put("password", password);
            requestMap.put("code", code);
            requestMap.put("invitecode", invitecode);
            requestMap.put("trade_password", "123456");
            requestMap.put("team_id", "");
            requestMap.put("t", current);
            // {"code":0,"result":{},"msg":"账号已存在"}
            String resultStr = HttpUtils.sendPost(url, "mobile=" + mobile + "&password=" + password + "&code=" + code + "&invitecode=" + invitecode + "&trade_password=123456&team_id=&t=" + current + "&sign=" + getSign(requestMap));
            if (StringUtils.isNotBlank(resultStr)) {
                JSONObject jsonObject = JSONObject.parseObject(resultStr);
                if (jsonObject != null) {
                    if (jsonObject.get("code") != null && "1".equalsIgnoreCase(String.valueOf(jsonObject.get("code")))) {
                        return ResultVo.success("", "注册成功");
                    } else {
                        return ResultVo.error(ResultCode.ERROR, String.valueOf(jsonObject.get("msg")));
                    }
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return ResultVo.error(ResultCode.ERROR, "注册失败");
    }

    @ApiOperation(notes = "login", httpMethod = "POST", value = "用户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "string"),
    })
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public ResultVo login(String mobile, String password, HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isEmpty(mobile)) {
            return ResultVo.error(ResultCode.ERROR, "手机号不能为空");
        }
        if (StringUtils.isEmpty(password)) {
            return ResultVo.error(ResultCode.ERROR, "密码不能为空");
        }
        User user = userService.findByMobile(mobile);
        if (user == null) {
            return ResultVo.error(ResultCode.ERROR, "手机号不存在");
        }
        String passwordMd5 = MD5.parseMD5(MD5.parseMD5(password) + user.getSalt());
        if (!passwordMd5.equals(user.getPassword())) {
            return ResultVo.error(ResultCode.ERROR, "密码错误，请重新输入");
        }
        StoreGuide storeGuide = storeGuideService.findByUserId(user.getId());
        if (storeGuide != null) {
            user.setIsStoreGuide(1);
            user.setStoreGuideId(storeGuide.getId());
        }
        user.setSalt("");
        user.setPassword("");
        user.setAvatar(rongyaotuadminDomain + user.getAvatar());
        Map<String, Object> resultMap = new HashMap<>();
        String userToken = IdGen.uuid();
        user.setUserToken(userToken);
        String key = RedisConstant.USER_TOKEN_KEY + userToken;
        RedisUtil.set(key, user, 3600 * 24 * 7);

        List<FacePayConfig> facePayConfigList = facePayConfigService.find(90, 1, null);
        String showAccountAuth = "0";
        if (facePayConfigList != null && !facePayConfigList.isEmpty()) {
            showAccountAuth = facePayConfigList.get(0).getValue();
        }
        user.setShowAccountAuth(showAccountAuth);
        resultMap.put("user", user);
        return ResultVo.success(resultMap, "成功");
    }

    @ApiOperation(notes = "resetPassword", httpMethod = "POST", value = "忘记密码，找回密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, paramType = "query", dataType = "string"),
    })
    @RequestMapping(value = "resetPassword", method = RequestMethod.POST)
    public ResultVo resetPassword(String mobile, String password, String code, HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isEmpty(mobile)) {
            return ResultVo.error(ResultCode.ERROR, "手机号不能为空");
        }
        if (StringUtils.isEmpty(password)) {
            return ResultVo.error(ResultCode.ERROR, "密码不能为空");
        }
        if (StringUtils.isEmpty(code)) {
            return ResultVo.error(ResultCode.ERROR, "验证码不能为空");
        }
        try {
            //现有的用户注册，http://yun2.dianbang-st.com/apiv1/user/resetPassword
            // 注册接口参数有mobile,password,code
            String url = rongyaotuapiDomain + "/apiv1/user/resetPassword";
            String current = System.currentTimeMillis() + "";
            Map requestMap = new HashMap<>();
            requestMap.put("mobile", mobile);
            requestMap.put("password", password);
            requestMap.put("code", code);
            requestMap.put("t", current);
            String resultStr = HttpUtils.sendPost(url, "mobile=" + mobile + "&password=" + password + "&code=" + code + "&t=" + current + "&sign=" + getSign(requestMap));
            if (StringUtils.isNotBlank(resultStr)) {
                JSONObject jsonObject = JSONObject.parseObject(resultStr);
                if (jsonObject != null) {
                    if (jsonObject.get("code") != null && "1".equalsIgnoreCase(String.valueOf(jsonObject.get("code")))) {
                        return ResultVo.success("", "重置成功");
                    } else {
                        return ResultVo.error(ResultCode.ERROR, String.valueOf(jsonObject.get("msg")));
                    }
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return ResultVo.error(ResultCode.ERROR, "重置失败");
    }

//    @ApiOperation(notes = "bindMobile", httpMethod = "POST", value = "用户绑定手机")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "openid", value = "用户openid", required = true, paramType = "query", dataType = "string"),
//            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, paramType = "query", dataType = "string"),
//            @ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "query", dataType = "string"),
//
//    })
//    @RequestMapping(value = "bindMobile", method = RequestMethod.POST)
//    public ResultVo bindPhone(String openid, String mobile, String code, HttpServletRequest request, HttpServletResponse response) {
//        if (StringUtils.isEmpty(openid)) {
//            return ResultVo.error(ResultCode.ERROR, "用户openid不能为空");
//        }
//        if (StringUtils.isEmpty(mobile)) {
//            return ResultVo.error(ResultCode.ERROR, "手机号码不能为空");
//        }
//        if (StringUtils.isEmpty(code)) {
//            return ResultVo.error(ResultCode.ERROR, "验证码不能为空");
//        }
//        String mobileCode = (String) RedisUtil.get(mobile);
//        if (StringUtils.isBlank(mobileCode)) {
//            return ResultVo.error(ResultCode.ERROR, "验证码已过期，请重新获取");
//        }
//        if (!mobileCode.equals(code)) {
//            return ResultVo.error(ResultCode.ERROR, "验证码错误,请重新输入");
//        }
//        WxUser wxUser = wxUserService.findBySmallOpenId(openid);
//        if (wxUser != null) {
//            return ResultVo.error(ResultCode.ERROR, "当前用户已绑定手机");
//        }
//        User user = userService.findByMobile(mobile);
//        if (user == null) {
//            return ResultVo.error(ResultCode.ERROR, "亲，您还没有注册成为我们的会员，请稍等");
//        }
//        StoreGuide storeGuide = storeGuideService.findByUserId(user.getId());
//        if (storeGuide != null) {
//            user.setIsStoreGuide(1);
//        }
//        wxUser = new WxUser();
//        wxUser.setUserId(user.getId());
//        wxUser.setSmallOpenId(openid);
//        wxUserService.insert(wxUser);
//        Map<String, Object> resultMap = new HashMap<>();
//        resultMap.put("user", user);
//        return ResultVo.success(resultMap, "获取成功");
//    }

    public static String keyStr = "daemv65dstOf!ZQo91JvfKzg0L%N@mZgCk8Gq36F9udg";

    // 解决输入中文加密问题
    public static String getSign(Map<String, String> map) {
        Set set = map.keySet();
        Object[] arr = set.toArray();
        Arrays.sort(arr);
        StringBuilder sb = new StringBuilder();
        for (Object key : arr) {
            sb.append(key + map.get(key).toString());
        }
        String m = sb.toString() + keyStr;
        return md5(m);
    }

    public static String md5(String string) {
        if (StringUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(string.getBytes());
            StringBuilder result = new StringBuilder();
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result.append(temp);
            }
            return result.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
}
